package beans;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import model.Host;
import model.User;
import webservice.NodeCommunicationWS;
import exceptions.UsernameExistsException;

/**
 * Session Bean implementation class ChatData
 */
@Singleton
@Startup
@LocalBean
public class ChatData implements ChatDataLocal {

	private HashMap<String, User> registeredUsers;
	private ArrayList<User> loggedUsers;
	private ArrayList<Host> hosts;
	private Host localHost;
	private final String httpHeader = "";//"http://";
	private String defaultHostAddress;// = "192.168.1.23";
	private String thisServerAddress;
	private final String wsdlLocation = "";//":8080/chatAgentsEJB/NodeCommunication/NodeCommunicationBean?wsdl";
	private final QName serviceName = new QName("http://1337.webservice",
			"NodeCommunication");
	private boolean first;// = true;

	NodeCommunicationWS service;

	/**
	 * Default constructor.
	 */
	public ChatData() {

	}

	@PostConstruct
	@Override
	public void init() {

		// Ucitavanje adrese iz konfiguracionog fajla
		Properties prop = new Properties();
		InputStream input = null;

		try {

			input = new FileInputStream(
					"../standalone/deployments/chatAgentsEAR.ear/config.properties");

			// load a properties file
			prop.load(input);

			// get the property value and print it out
			thisServerAddress = prop.getProperty("ServerAddress");
			defaultHostAddress = prop.getProperty("defaultHostAddress");
			String firstt = prop.getProperty("isBootingFirst");
			if (firstt.toLowerCase().equals("true")) {
				first = true;
			} else {
				first = false;
			}

		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		// Ucitavanje adrese iz konfiguracionog fajla
		/////////////////////////////////////////////////////////////////////////////////
		loggedUsers = new ArrayList<User>();
		registeredUsers = new HashMap<String, User>();
		hosts = new ArrayList<Host>();
		//localHost = new Host("http://"+thisServerAddress+":8080/chatAgentsEJB/NodeCommunication/NodeCommunicationBean?wsdl", null);
		localHost = new Host(thisServerAddress, null);
		hosts.add(localHost);

		// filovanje torte
		String usernames[] = { "admin", "medo maddalena", "kecimirovic",
				"kmihalek kasinder", "finaru fantashi kuraudo-san" };
		String password = "pass";
		for (String u : usernames) {
			registeredUsers.put(u, new User(u, password, localHost));
		}
		///////////////////////////////////////////////////////////////////////////////////
		// registracija kod ostalih cvorova

		if (!first) {
			try {
				Service temp = Service.create(new URL(httpHeader
						+ defaultHostAddress + wsdlLocation), serviceName);
				service = temp.getPort(NodeCommunicationWS.class);
				System.out.println(httpHeader + defaultHostAddress
						+ wsdlLocation);
				List<Host> hostsRemote = service.register(localHost);
				loggedUsers.addAll(service.getAllUsers());
				service.updateUserList(loggedUsers);
				// service.notifyRegister(localHost);
				// if(hostsRemote!=null) hosts.addAll(hostsRemote);
				if (hostsRemote != null) {
					for (Host h : hostsRemote) {
						if (!hosts.contains(h)) {
							hosts.add(h);
						}
					}
				}
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public User register(String username, String password)
			throws UsernameExistsException {
		User newUser = new User(username, password, localHost);
		if (registeredUsers.containsKey(username)) {
			throw new UsernameExistsException();
		} else
			registeredUsers.put(username, newUser);
		return newUser;
	}

	@Override
	public boolean login(User login) {
		boolean retVal = false;
		if (registeredUsers.containsKey(login.getUsername())
				&& !loggedUsers.contains(login)) {
			loggedUsers.add(login);
			retVal = true;
		}
		return retVal;
	}

	@Override
	public boolean logout(User user) {
		boolean retVal = false;
		if (loggedUsers.remove(user))
			retVal = true;
		return retVal;
	}

	@Override
	public ArrayList<User> getAllUsers() {
		return loggedUsers;
	}

	@Override
	public ArrayList<Host> getHosts() {
		// TODO Auto-generated method stub
		return hosts;
	}

	@Override
	public Host getLocalHost() {
		// TODO Auto-generated method stub
		return localHost;
	}

	@Override
	public String getHttpHeader() {
		return httpHeader;
	}

	@Override
	public String getWsdlLocation() {
		return wsdlLocation;
	}

	@Override
	public QName getServiceName() {
		return serviceName;
	}

	@Override
	public User getUser(String username) {
		return registeredUsers.get(username);
	}

	@PreDestroy
	private void notifyShutdown() {
		Service temp;
		try {
			temp = Service.create(new URL(httpHeader + defaultHostAddress
					+ wsdlLocation), serviceName);
			service = temp.getPort(NodeCommunicationWS.class);
			service.unregister(localHost);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
